package com.tianruan.dc.modules.sys.user.api;

import cn.hutool.core.util.StrUtil;
import com.tianruan.dc.common.utils.OSSUtils;
import com.tianruan.dc.common.utils.response.VResponse;
import com.tianruan.dc.modules.BigModelNew.component.XfXhStreamClient;
import com.tianruan.dc.modules.BigModelNew.config.XfXhConfig;
import com.tianruan.dc.modules.BigModelNew.controller.BigModelNewController;
import com.tianruan.dc.modules.BigModelNew.dto.MsgDTO;
import com.tianruan.dc.modules.BigModelNew.listener.XfXhWebSocketListener;
import com.tianruan.dc.modules.sys.user.entity.dto.LearnPathDTO;
import com.tianruan.dc.modules.sys.user.service.ILearnPathService;
import com.tianruan.dc.modules.sys.user.service.impl.LearnPathServiceImpl;
import com.tianruan.dc.modules.userinfo.result.PageResult;
import lombok.extern.slf4j.Slf4j;
import okhttp3.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Calendar;
import java.util.Collections;
import java.util.UUID;

import static com.tianruan.dc.common.constant.GlobalExceptionEnum.DUPLICATE_USERNAME;
import static com.tianruan.dc.common.constant.GlobalExceptionEnum.SUCCESS;

/**
 * @Author: AmiroKD
 * @CreateTime: 2024-07-06
 * @Version: 1.0
 */

/**
 * 学习路线规划
 */
@RestController
@RequestMapping("/api/learnPath")
@Slf4j
public class LearnPathController {

    @Autowired
    private ILearnPathService iLearnPathService;

    @Resource
    private XfXhStreamClient xfXhStreamClient;

    @Resource
    private XfXhConfig xfXhConfig;
    @Autowired
    private LearnPathServiceImpl learnPathServiceImpl;

    /**
     * 新增学科学习路线
     *
     * @param learnPathDTO
     * @return
     */
    @PostMapping("/add")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:teacher')")
    public VResponse<Object> saveLearnPath(@RequestBody LearnPathDTO learnPathDTO) {
        //判断是否已经存在此学科
        boolean isSubjectExist = iLearnPathService.isSubjectExist(learnPathDTO.getSubject());
        if (!isSubjectExist) {
            return VResponse.error(1000, "已存在相关学科的学习指南");
        }
//        //上传文件
//        String content = null;
//        try {
//            if (file != null) {
//                //获取文件名
//                String originalFilename = file.getOriginalFilename();
//                if (originalFilename != null && !originalFilename.isEmpty()) {
//                    //获取最后一个"."的位置
//                    int cutPoint = originalFilename.lastIndexOf(".");
//                    //获取文件名
//                    String prefix = originalFilename.substring(0, cutPoint);
//                    //获取后缀名
//                    String suffix = originalFilename.substring(cutPoint + 1);
//
//                    if (prefix.length() > 50) {
//                        return VResponse.error(1000, "上传的文件名称过长");
//                    }
//
//                    Calendar calendar = Calendar.getInstance();
//                    content = OSSUtils.uploadFileInputSteam("/file/" + calendar.get(Calendar.YEAR) + "/" +
//                            (calendar.get(Calendar.MONTH) + 1) + "/" + calendar.get(Calendar.DAY_OF_MONTH) + "/", file);
//                }
//            }
//            LearnPathDTO learnPathDTO = new LearnPathDTO();
//            learnPathDTO.setSubject(subject);
//            learnPathDTO.setCreateId(createId);

        log.info("新增学科学习路线：{},{}", learnPathDTO.getSubject(), learnPathDTO.getContent());
        learnPathDTO.setContent(learnPathDTO.getContent());
        iLearnPathService.saveLeanPath(learnPathDTO);
        return VResponse.success("成功添加新增学科学习路线");
//        } catch (Exception e) {
//            throw new RuntimeException(e);

//        }
    }

    /**
     * 删除学科学习路线
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:teacher')")
    public VResponse<Object> deleteLearnPath(@PathVariable String id) {
        try {
//            判断是否存在此学科
            boolean isSubjectExist = iLearnPathService.isSubjectIdExist(id);
            if (isSubjectExist) {
                return VResponse.error(1000, "不存在相关学科的学习指南");
            }
//            //根据学科名称获取id
//            String id = iLearnPathService.getIdBySubject(subject);
            iLearnPathService.deleteSubject(id);
            return VResponse.success("成功删除学科学习指南");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据ID查询学习指南
     *
     * @param id
     * @return
     */
    @GetMapping("/selectById")
    public VResponse selectById(@RequestParam("id") String id) {
        log.info("查询的学习指南id为{}", id);
        LearnPathDTO learnPathDTO = learnPathServiceImpl.selectById(id);
        return VResponse.success(learnPathDTO);
    }

    /**
     * 查询回显学科学习路线的相关信息
     *
     * @param learnPathDTO
     * @return
     */
    @GetMapping("/select")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:teacher','sys:student')")
    public VResponse<PageResult> selectLearnPath(LearnPathDTO learnPathDTO) {
        log.info("学习路线分页查询：参数为：{}", learnPathDTO);
        PageResult pageResult = iLearnPathService.selectLearnPath(learnPathDTO);
        return VResponse.success(pageResult);
    }

    /**
     * 发送问题
     *
     * @param question 问题
     * @return 星火大模型的回答
     */
    @GetMapping("/sendQuestion")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:teacher','sys:student')")
    public VResponse sendQuestion(@RequestParam("question") String question) {
        // 存入接口地址
        xfXhConfig.setHostUrl("https://spark-openapi.cn-huabei-1.xf-yun.com/v1/assistants/w6kc94o7vhg8_v1");
        // 如果是无效字符串，则不对大模型进行请求nio
        if (StrUtil.isBlank(question)) {
            return VResponse.error(1001, "无效问题，请重新输入");
        }
        // 获取连接令牌
        if (!xfXhStreamClient.operateToken(XfXhStreamClient.GET_TOKEN_STATUS)) {
            return VResponse.error(1002, "当前大模型连接数过多，请稍后再试");
        }

        // 创建消息对象
        MsgDTO msgDTO = MsgDTO.createUserMsg(question);
        // 创建监听器
        XfXhWebSocketListener listener = new XfXhWebSocketListener();
        // 发送问题给大模型，生成 websocket 连接
        WebSocket webSocket = xfXhStreamClient.sendMsg(UUID.randomUUID().toString().substring(0, 10), Collections.singletonList(msgDTO), listener);
        if (webSocket == null) {
            // 归还令牌
            xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
            return VResponse.error(1000, "系统内部错误，请联系管理员");
        }
        try {
            int count = 0;
            // 为了避免死循环，设置循环次数来定义超时时长
            int maxCount = xfXhConfig.getMaxResponseTime() * 5;
            while (count <= maxCount) {
                Thread.sleep(200);
                if (listener.isWsCloseFlag()) {
                    break;
                }
                count++;
            }
            if (count > maxCount) {
                return VResponse.error(1003, "大模型响应超时，请联系管理员");
            }
            //重新存入content <!!!!这里获得返回的数据!!!!>
            String content = listener.getAnswer().toString();
//            System.out.println(content);
            msgDTO.setContent(content);
            // 响应大模型的答案
            return VResponse.success(content);

        } catch (InterruptedException e) {
            log.error("错误：" + e.getMessage());
            return VResponse.error(1500, "系统内部错误，请联系管理员");
        } finally {
            // 关闭 websocket 连接
            webSocket.close(1000, "");
            // 归还令牌
            xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
        }
    }


}
